#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

// 观察者接口
class Observer {
public:
    virtual void update(const std::string& obstacleStatus) = 0;
};

// 主题接口
class Subject {
public:
    virtual void attach(Observer* observer) = 0;
    virtual void detach(Observer* observer) = 0;
    virtual void notify(const std::string& obstacleStatus) = 0;
};

class Module {
protected:
    std::string id; // 模块编号

public:
    Module() : id("") {}
    explicit Module(const std::string& id) : id(id) {}

    void setId(const std::string& newId) { id = newId; }
    std::string getId() const { return id; }

    virtual void print() const = 0;
    virtual void saveToFile(std::ofstream& file) const = 0;
};

class LaserRadar : public Module, public Subject {
private:
    std::string model;
    int channels;
    int range;
    int powerConsumption;
    std::vector<Observer*> observers;

public:
    LaserRadar(const std::string& id, const std::string& model, int channels, int range, int powerConsumption)
        : Module(id), model(model), channels(channels), range(range), powerConsumption(powerConsumption) {}

    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    void detach(Observer* observer) override {
        auto it = std::find(observers.begin(), observers.end(), observer);
        if (it != observers.end()) {
            observers.erase(it);
        }
    }

    void notify(const std::string& obstacleStatus) override {
        for (auto* obs : observers) {
            obs->update(obstacleStatus);
        }
    }

    void print() const override {
        std::cout << "多线激光雷达信息: 编号=" << id << ", 型号=" << model << ", 通道数=" << channels
                  << ", 测试范围=" << range << "m" << ", 功耗=" << powerConsumption << "W" << std::endl;
    }

    void saveToFile(std::ofstream& file) const override {
        if (file.is_open()) {
            file << "多线激光雷达信息: 编号=" << id << ", 型号=" << model << ", 通道数=" << channels
                 << ", 测试范围=" << range << "m" << ", 功耗=" << powerConsumption << "W\n";
        }
    }
};

class Chassis : public Module, public Observer {
private:
    std::string model;
    int wheelBase;
    int trackWidth;
    int groundClearance;
    int minTurningRadius;
    std::string driveType;
    int maxTravelDistance;
    int numTires;
    std::string tireModel;
    int tireSize;
    LaserRadar& laserRadar; // 引用外部的 LaserRadar 对象


public:
    // 构造函数接受 LaserRadar 的引用
    Chassis(LaserRadar& lr, const std::string& id, const std::string& model, int wheelBase, int trackWidth, int groundClearance, 
            int minTurningRadius, std::string driveType, int maxTravelDistance, int numTires, std::string tireModel, int tireSize)
        : Module(id), model(model), wheelBase(wheelBase), trackWidth(trackWidth), groundClearance(groundClearance),
          minTurningRadius(minTurningRadius), driveType(driveType), maxTravelDistance(maxTravelDistance),
          numTires(numTires), tireModel(tireModel), tireSize(tireSize), laserRadar(lr) {
        laserRadar.attach(this); // 注册为观察者
    }

    void print() const override {
        std::cout << "底盘信息: 编号=" << id << ", 型号=" << model << ", 轴距=" << wheelBase << "mm"
                  << ", 轮距=" << trackWidth << "mm" << ", 最小离地间隙=" << groundClearance << "mm"
                  << ", 最小转弯半径=" << minTurningRadius << "m" << ", 驱动形式=" << driveType
                  << ", 最大行程=" << maxTravelDistance << "km" << ", 轮胎数量=" << numTires
                  << ", 轮胎型号=" << tireModel << ", 轮胎尺寸=" << tireSize << "mm" << std::endl;
    }

    void saveToFile(std::ofstream& file) const override {
        if (file.is_open()) {
            file << "底盘信息: 编号=" << id << ", 型号=" << model << ", 轴距=" << wheelBase << "mm"
                 << ", 轮距=" << trackWidth << "mm" << ", 最小离地间隙=" << groundClearance << "mm"
                 << ", 最小转弯半径=" << minTurningRadius << "m" << ", 驱动形式=" << driveType
                 << ", 最大行程=" << maxTravelDistance << "km" << ", 轮胎数量=" << numTires
                 << ", 轮胎型号=" << tireModel << ", 轮胎尺寸=" << tireSize << "mm\n";
        }
    }
    void update(const std::string& obstacleStatus) override {
        if (obstacleStatus == "前方") {
            std::cout << "后退..." << std::endl;
        } else if (obstacleStatus == "右前方") {
            std::cout << "左转..." << std::endl;
        } else if (obstacleStatus == "左前方") {
            std::cout << "右转..." << std::endl;
        }
    }
};

class AGXKit : public Module {
private:
    std::string model;
    int aiPerformance;
    int cudaCores;
    int tensorCores;
    int vram;
    int storage;

public:
    AGXKit() : Module() {}
    AGXKit(const std::string& id, const std::string& model, int aiPerformance, int cudaCores, int tensorCores, int vram, int storage)
        : Module(id), model(model), aiPerformance(aiPerformance), cudaCores(cudaCores), tensorCores(tensorCores),
          vram(vram), storage(storage) {}

    void print() const override {
        std::cout << "AGX套件信息: 编号=" << id << ", 型号=" << model << ", AI性能=" << aiPerformance << "TOPS"
                  << ", CUDA核心=" << cudaCores << ", Tensor CORE=" << tensorCores
                  << ", 显存=" << vram << "GB" << ", 存储=" << storage << "GB" << std::endl;
    }

    void saveToFile(std::ofstream& file) const override {
        if (file.is_open()) {
            file << "AGX套件信息: 编号=" << id << ", 型号=" << model << ", AI性能=" << aiPerformance << "TOPS"
                 << ", CUDA核心=" << cudaCores << ", Tensor CORE=" << tensorCores
                 << ", 显存=" << vram << "GB" << ", 存储=" << storage << "GB\n";
        }
    }
};

class StereoCamera : public Module {
private:
    std::string model;
    std::string cameraModel;
    std::string rgbResolution;
    int rgbFramerate;
    std::string fov;
    int depthFramerate;

public:
    StereoCamera() : Module() {}
    StereoCamera(const std::string& id, const std::string& model, const std::string& cameraModel, const std::string& rgbResolution, int rgbFramerate,
                 const std::string& fov, int depthFramerate)
        : Module(id), model(model), cameraModel(cameraModel), rgbResolution(rgbResolution), rgbFramerate(rgbFramerate),
fov(fov), depthFramerate(depthFramerate) {}

    void print() const override {
        std::cout << "双目摄像头信息: 编号=" << id << ", 型号=" << model << ", 摄像头=" << cameraModel
                  << ", RGB帧分辨率=" << rgbResolution << ", RGB帧率=" << rgbFramerate
                  << ", FOV=" << fov << ", 深度帧率=" << depthFramerate << std::endl;
    }

    void saveToFile(std::ofstream& file) const override {
        if (file.is_open()) {
            file << "双目摄像头信息: 编号=" << id << ", 型号=" << model  << ", 摄像头=" << cameraModel<< ", RGB帧分辨率=" << rgbResolution << ", RGB帧率=" << rgbFramerate<< ", FOV=" << fov << ", 深度帧率=" << depthFramerate << endl;
        }
    }
};

class Gyroscope : public Module {
private:
std::string model;
std::string manufacturer;

public:
Gyroscope() : Module() {}
Gyroscope(const std::string& id, const std::string& model, const std::string& manufacturer)
: Module(id), model(model), manufacturer(manufacturer) {}

void print() const override {
    std::cout << "9轴陀螺仪信息: 编号=" << id << ", 型号=" << model << ", 厂家=" << manufacturer << std::endl;
}

void saveToFile(std::ofstream& file) const override {
    if (file.is_open()) {
        file << "9轴陀螺仪信息: 编号=" << id << ", 型号=" << model << ", 厂家=" << manufacturer << "\n";
    }
}
};

class LCD : public Module {
private:
int size;
std::string model;

public:
LCD() : Module() {}
LCD(const std::string& id, int size, const std::string& model)
: Module(id), size(size), model(model) {}

void print() const override {
    std::cout << "液晶显示屏信息: 编号=" << id << ", 尺寸=" << size << "英寸" << ", 型号=" << model << std::endl;
}

void saveToFile(std::ofstream& file) const override {
    if (file.is_open()) {
        file << "液晶显示屏信息: 编号=" << id << ", 尺寸=" << size << "英寸" << ", 型号=" << model << "\n";
    }
}
};

class Battery : public Module {
private:
std::string voltage;
std::string capacity;
std::string outputVoltage;
std::string chargingTime;

public:
Battery() : Module() {}
Battery(const std::string& id, const std::string& voltage, const std::string& capacity, const std::string& outputVoltage, const std::string& chargingTime)
: Module(id), voltage(voltage), capacity(capacity), outputVoltage(outputVoltage), chargingTime(chargingTime) {}

void print() const override {
    std::cout << "电池模块信息: 编号=" << id << ", 参数=" << voltage << "/" << capacity
              << ", 对外供电=" << outputVoltage << ", 充电时长=" << chargingTime << "小时" << std::endl;
}

void saveToFile(std::ofstream& file) const override {
    if (file.is_open()) {
        file << "电池模块信息: 编号=" << id << ", 参数=" << voltage << "/" << capacity
             << ", 对外供电=" << outputVoltage << ", 充电时长=" << chargingTime << "小时\n";
    }
}
};

class SmartCar : public Module {
private:
std::string carId;
Chassis chassis;
AGXKit agxKit;
StereoCamera stereoCamera;
LaserRadar laserRadar;
Gyroscope gyroscope;
LCD lcd;
Battery battery;

public:
SmartCar(const std::string& carId, Chassis chassis, AGXKit agxKit, StereoCamera stereoCamera, LaserRadar laserRadar,
Gyroscope gyroscope, LCD lcd, Battery battery)
: Module(carId), carId(carId), chassis(chassis), agxKit(agxKit), stereoCamera(stereoCamera), laserRadar(laserRadar),
gyroscope(gyroscope), lcd(lcd), battery(battery) {}

void print() const {
    std::cout << "智能小车信息: 编号=" << carId << std::endl;
    chassis.print();
    agxKit.print();
    stereoCamera.print();
    laserRadar.print();
    gyroscope.print();
    lcd.print();
    battery.print();
}

void saveToFile(std::ofstream& file) const {
    chassis.saveToFile(file);
    agxKit.saveToFile(file);
    stereoCamera.saveToFile(file);
    laserRadar.saveToFile(file);
    gyroscope.saveToFile(file);
    lcd.saveToFile(file);
    battery.saveToFile(file);
}
};

class Student : public Module {
private:
std::string studentId;
std::string name;
SmartCar car;

public:
Student(const std::string& studentId, const std::string& name, SmartCar car)
: Module(studentId), studentId(studentId), name(name), car(car) {}

void print() const {
    std::cout << "学生信息: 学号=" << studentId << ", 姓名=" << name << std::endl;
    car.print();
}

void saveToFile(std::ofstream& file) const {
    if (file.is_open()) {
        file << "学生信息: 学号=" << studentId << ", 姓名=" << name << "\n";
        car.saveToFile(file);
    }
}
};